package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
	"time"

	"github.com/gorilla/websocket"
)

func main() {

	// 从标准输入流中接收输入数据
	input := bufio.NewScanner(os.Stdin)

	appId, senderId, password := 101, "", ""

	for {
		fmt.Printf("请输入用户id:\n")
		if input.Scan() {
			senderId = input.Text()
		}

		fmt.Printf("请输入密码:\n")
		if input.Scan() {
			password = input.Text()
		}

		// todo
		res, err := http.Get(
			"http://" + "LAPTOP-J6QC41QI:10241/user/login" +
				fmt.Sprintf("?app_id=%d&user_id=%s&password=%s", appId, senderId, password),
		)

		if err != nil {
			fmt.Println(err.Error())
		}

		resp := make(map[string]interface{})
		// read http response body
		temp, err := io.ReadAll(res.Body)
		if err != nil {
			fmt.Println(err.Error())
		}

		// unmashal body data into temp
		if err := json.Unmarshal(temp, &resp); err != nil {
			fmt.Println(err.Error())
		}

		fmt.Println(resp)

		if int(resp["code"].(float64)) != 200 {
			fmt.Printf("登陆失败: %s\n\n", resp["code"])
			fmt.Printf("登陆失败: %s\n\n", resp["msg"])
			continue
		}

		/*data := make(map[string]interface{})
		if err := json.Unmarshal([]byte(resp["data"].(map[string]interface{})), &data); err != nil {
			fmt.Println(err.Error())
		}*/

		fmt.Printf("%s, token: %s\n\n", resp["msg"], resp["data"])
		break
	}

	fmt.Printf("正在升级为websocket连接...\n\n")

	/* 升级为websocket连接*/
	conn, response, err := websocket.DefaultDialer.Dial(
		fmt.Sprintf("ws://LAPTOP-J6QC41QI:10241/user/ws?token=123&app_id=101&user_id=%s", senderId), nil)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(response)
	fmt.Println("建立websocket连接成功")

	go func() {
		for {
			_, p, err := conn.ReadMessage()
			if err != nil {
				fmt.Println(err)
			}

			//time.Sleep(10 * time.Second)
			fmt.Printf("\n**************** new message ****************\n")
			//fmt.Printf("From: %d\n", 1002)
			fmt.Printf("%s\n", string(p))
			fmt.Printf("*********************************************\n\n")
			fmt.Printf("[发送消息]:\n")
			fmt.Printf("To: ")
		}
	}()

	// 逐行扫描, 发送消息
	for {
		req := map[string]interface{}{}
		req["cmd"] = "chat"
		data := map[string]interface{}{}
		data["app_id"] = uint32(appId)
		data["type"] = "text"
		data["sender_id"], _ = strconv.ParseInt(senderId, 10, 64)
		data["sent_time"] = time.Now().Unix()

		req["data"] = data

		fmt.Printf("[发送消息]\n")
		fmt.Printf("To: ")
		if input.Scan() {
			data["reciever_id"], _ = strconv.ParseInt(input.Text(), 10, 64)
		}

		fmt.Printf("Content: ")
		if input.Scan() {
			data["content"] = input.Text()
		}

		requestData, _ := json.Marshal(req)
		if err := conn.WriteMessage(websocket.TextMessage, requestData); err != nil {
			fmt.Printf("发送消息失败: %s\n\n", err.Error())
		}

		//fmt.Printf("To: %s, Content: %s\n\n", data["reciever_id"], data["content"])
	}

}

/*
func main() {
	mu := sync.Mutex{}
	conns := []*websocket.Conn{}
	var count int64 = 0
	// 连接WebSocket服务器
	wg := &sync.WaitGroup{}
	for i := 0; i < 200; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			conn, _, err := websocket.DefaultDialer.Dial("ws://LAPTOP-J6QC41QI:10240/user/ws", nil)
			if err != nil {
				log.Fatal(err)
			}

			fmt.Println("建立websocket连接成功")

			mu.Lock()
			conns = append(conns, conn)
			mu.Unlock()
		}()
	}
	wg.Wait()
	fmt.Println("200 connections connected")

	// 发送消息
	for i := 0; i < 200; i++ {
		req := map[string]interface{}{}
		req["cmd"] = "chat"
		data := map[string]interface{}{}
		data["app_id"] = 1
		data["type"] = "text"
		data["msg"] = fmt.Sprintf("hello world %d", i)
		data["sender_id"] = 2
		data["reciever_id"] = 2
		data["time"] = 14894793249249

		req["data"] = data
		//requestData, _ := json.Marshal(req)
		//err := conns[i].WriteMessage(websocket.TextMessage, requestData)
		//if err != nil {
		//	log.Fatal(err)
		//}
	}

	// 读取消息
	for i := 0; i < 200; i++ {
		wg.Add(1)
		go func(j int) {
			defer wg.Done()
			for k := 0; k < 100; k++ {
				_, p, err := conns[j].ReadMessage()
				if err != nil {
					log.Fatal(err)
				}
				atomic.AddInt64(&count, 1)
				log.Printf("Received message: %s, count: %d", string(p), count)
			}
		}(i)
	}
	wg.Wait()
}
*/
